package utils;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;


    /**
    * @ClassName: UtilJackson
    * @Description: 该工具类使用时，需建立对象
    * @author 宁少林
    * @date 2016年8月29日
    *
    */

    /**
    * @ClassName: UtilJackson
    * @Description: TODO
    * @author 宁少林
    * @date 2016年9月1日
    *
    */

    /**
    * @ClassName: UtilJackson
    * @Description: TODO
    * @author 宁少林
    * @date 2016年9月1日
    *
    */
public class UtilJackson {
	private ObjectMapper objectMapper;  
	  
    public static UtilJackson me() {  
        return new UtilJackson();  
    }  
  
    public static String getJson(Object object){
    	UtilJackson utilJackson=me();
    	String josnString=utilJackson.object2Json(object);
    	//System.out.println(josnString);
    	return josnString;
    }
    
    private UtilJackson() {  
        objectMapper = new ObjectMapper();  
        // 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性  
     // to prevent exception when encountering unknown property:
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
		// to allow serialization of "empty" POJOs (no properties to serialize)
		// (without this setting, an exception is thrown in those cases)
        objectMapper.enable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
  
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));  
    }  
    
    /*  1.实体上
    @JsonInclude(Include.NON_NULL) 
    //将该标记放在属性上，如果该属性为NULL则不参与序列化
    //如果放在类上边,那对这个类的全部属性起作用
    //Include.Include.ALWAYS 默认
    //Include.NON_DEFAULT 属性为默认值不序列化
    //Include.NON_EMPTY 属性为 空（“”） 或者为 NULL 都不序列化
    //Include.NON_NULL 属性为NULL 不序列化
    
    2.代码上
    ObjectMapper mapper = new ObjectMapper();
    mapper.setSerializationInclusion(Include.NON_NULL);  
    //通过该方法对mapper对象进行设置，所有序列化的对象都将按改规则进行系列化
    //Include.Include.ALWAYS 默认
    //Include.NON_DEFAULT 属性为默认值不序列化
    //Include.NON_EMPTY 属性为 空（“”） 或者为 NULL 都不序列化
    //Include.NON_NULL 属性为NULL 不序列化 
   */    
    public UtilJackson setSerializationInclusion(Include include){
    	objectMapper.setSerializationInclusion(include);
    	return this;
    }
  
    public UtilJackson filter(String filterName, String... properties) {  
        FilterProvider filterProvider = new SimpleFilterProvider().addFilter(filterName,  
                SimpleBeanPropertyFilter.serializeAllExcept(properties));  
        objectMapper.setFilterProvider(filterProvider);  
        return this;  
    }  
  
    public UtilJackson addMixInAnnotations(Class<?> target, Class<?> mixinSource) {  
    	objectMapper.addMixIn(target, mixinSource);
        return this;  
    }  
  
    public UtilJackson setDateFormate(DateFormat dateFormat) {  
        objectMapper.setDateFormat(dateFormat);  
        return this;  
    }  
  
    public <T> T json2Obj(String json, Class<T> clazz) {  
        try {  
            return objectMapper.readValue(json, clazz);  
        } catch (Exception e) {  
            e.printStackTrace();  
            throw new RuntimeException("解析json错误");  
        }  
    }  
  
    public String object2JsonWithFilter(Object obj,String filterName, String... properties){
    	filter(filterName,properties);
    	try {
			return objectMapper.writeValueAsString(obj);
		} catch (JsonProcessingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new RuntimeException("解析对象错误");
		}  
    }
    
    public String object2Json(Object obj) {  
        try {  
            return objectMapper.writeValueAsString(obj);  
        } catch (Exception e) {  
            e.printStackTrace();  
            throw new RuntimeException("解析对象错误");  
        }  
    }  
  
    
        /**
        * @Title: json2List
        * @Description: 根据参数类型，返回ArrayList<T>
        * @param @param json
        * @param @param clazz  T的类型
        * @param @return
        * @param @throws JsonParseException
        * @param @throws JsonMappingException
        * @param @throws IOException    
        * @return List<T>    
        * @throws
        */
    public <T> List<T> json2List(String json,Class<T> clazz) throws JsonParseException, JsonMappingException, IOException {
    	JavaType javaType =objectMapper.getTypeFactory().constructParametricType(ArrayList.class, clazz);
    	List<T> list=objectMapper.readValue(json,javaType);
    	return list;
	}
    
    
        /**
        * @Title: json2Set
        * @Description: 根据参数类型，返回HashSet<T>
        * @param @param json
        * @param @param clazz
        * @param @return
        * @param @throws JsonParseException
        * @param @throws JsonMappingException
        * @param @throws IOException    
        * @return Set<T>    
        * @throws
        */
    public <T> Set<T> json2Set(String json,Class<T> clazz) throws JsonParseException, JsonMappingException, IOException {
    	JavaType javaType =objectMapper.getTypeFactory().constructParametricType(HashSet.class, clazz);
    	Set<T> set=objectMapper.readValue(json,javaType);
    	return set;
	}
    
    
    @SuppressWarnings("unchecked")  
    public List<Map<String, Object>> json2List(String json) {  
        try {  
            return objectMapper.readValue(json, List.class);  
        } catch (Exception e) {  
            e.printStackTrace();  
            throw new RuntimeException("解析json错误");  
        }  
    }  
	
}
